home *** CD-ROM | disk | FTP | other *** search
- DOUBLE PRECISION FUNCTION DZNRM2( N, ZX, INCX )
- *
- * unitary norm of the complex n-vector stored in zx() with storage
- * increment incx .
- * if n .le. 0 return with result = 0.
- * if n .ge. 1 then incx must be .ge. 1
- *
- * c.l.lawson , 1978 jan 08
- *
- * four phase method using two built-in constants that are
- * hopefully applicable to all machines.
- * cutlo = maximum of sqrt(u/eps) over all known machines.
- * cuthi = minimum of sqrt(v) over all known machines.
- * where
- * eps = smallest no. such that eps + 1. .gt. 1.
- * u = smallest positive no. (underflow limit)
- * v = largest no. (overflow limit)
- *
- * brief outline of algorithm..
- *
- * phase 1 scans zero components.
- * move to phase 2 when a component is nonzero and .le. cutlo
- * move to phase 3 when a component is .gt. cutlo
- * move to phase 4 when a component is .ge. cuthi/m
- * where m = n for x() real and m = 2*n for complex.
- *
- * values for cutlo and cuthi..
- * from the environmental parameters listed in the imsl converter
- * document the limiting values are as follows..
- * cutlo, s.p. u/eps = 2**(-102) for honeywell. close seconds are
- * univac and dec at 2**(-103)
- * thus cutlo = 2**(-51) = 4.44089e-16
- * cuthi, s.p. v = 2**127 for univac, honeywell, and dec.
- * thus cuthi = 2**(63.5) = 1.30438e19
- * cutlo, d.p. u/eps = 2**(-67) for honeywell and dec.
- * thus cutlo = 2**(-33.5) = 8.23181d-11
- * cuthi, d.p. same as s.p. cuthi = 1.30438d19
- * data cutlo, cuthi / 8.232d-11, 1.304d19 /
- * data cutlo, cuthi / 4.441e-16, 1.304e19 /
- *
- * .. Scalar Arguments ..
- INTEGER INCX, N
- * ..
- * .. Array Arguments ..
- COMPLEX*16 ZX( 1 )
- * ..
- * .. Local Scalars ..
- LOGICAL IMAG, SCALE
- INTEGER I, IX, NEXT, NN
- DOUBLE PRECISION ABSX, CUTHI, CUTLO, HITEST, ONE,
- $ SUM, XMAX, ZERO
- COMPLEX*16 ZDUMI, ZDUMR
- * ..
- * .. Intrinsic Functions ..
- INTRINSIC DABS, DSQRT, FLOAT
- * ..
- * .. Statement Functions ..
- DOUBLE PRECISION DIMAG, DREAL
- * ..
- * .. Statement Function definitions ..
- DREAL( ZDUMR ) = ZDUMR
- DIMAG( ZDUMI ) = ( 0.0D0, -1.0D0 )*ZDUMI
- * ..
- * .. Data statements ..
- DATA ZERO, ONE / 0.0D0, 1.0D0 /
- DATA CUTLO, CUTHI / 8.232D-11,
- $ 1.304D19 /
- * ..
- * .. Executable Statements ..
- IF( N.GT.0 )
- $ GO TO 10
- DZNRM2 = ZERO
- GO TO 140
- *
- 10 ASSIGN 20 TO NEXT
- SUM = ZERO
- IX = 1
- IF( INCX.LT.0 )
- $ IX = 1 - ( N-1 )*INCX
- NN = IX + ( N-1 )*INCX
- *
- * begin main loop
- *
- DO 130 I = IX, NN, INCX
- ABSX = DABS( DREAL( ZX( I ) ) )
- IMAG = .FALSE.
- GO TO NEXT( 20, 30, 60, 110, 70 )
- 20 IF( ABSX.GT.CUTLO )
- $ GO TO 100
- ASSIGN 30 TO NEXT
- SCALE = .FALSE.
- *
- * phase 1. sum is zero
- *
- 30 IF( ABSX.EQ.ZERO )
- $ GO TO 120
- IF( ABSX.GT.CUTLO )
- $ GO TO 100
- *
- * prepare for phase 2.
- *
- ASSIGN 60 TO NEXT
- GO TO 50
- *
- * prepare for phase 4.
- *
- 40 ASSIGN 70 TO NEXT
- SUM = ( SUM / ABSX ) / ABSX
- 50 SCALE = .TRUE.
- XMAX = ABSX
- GO TO 80
- *
- * phase 2. sum is small.
- * scale to avoid destructive underflow.
- *
- 60 IF( ABSX.GT.CUTLO )
- $ GO TO 90
- *
- * common code for phases 2 and 4.
- * in phase 4 sum is large. scale to avoid overflow.
- *
- 70 IF( ABSX.LE.XMAX )
- $ GO TO 80
- SUM = ONE + SUM*( XMAX / ABSX )**2
- XMAX = ABSX
- GO TO 120
- *
- 80 SUM = SUM + ( ABSX / XMAX )**2
- GO TO 120
- *
- * prepare for phase 3.
- *
- 90 SUM = ( SUM*XMAX )*XMAX
- *
- 100 ASSIGN 110 TO NEXT
- SCALE = .FALSE.
- *
- * for real or d.p. set hitest = cuthi/n
- * for complex set hitest = cuthi/(2*n)
- *
- HITEST = CUTHI / FLOAT( N )
- *
- * phase 3. sum is mid-range. no scaling.
- *
- 110 IF( ABSX.GE.HITEST )
- $ GO TO 40
- SUM = SUM + ABSX**2
- 120 CONTINUE
- *
- * control selection of real and imaginary parts.
- *
- IF( IMAG )
- $ GO TO 130
- ABSX = DABS( DIMAG( ZX( I ) ) )
- IMAG = .TRUE.
- GO TO NEXT( 30, 60, 110, 70 )
- *
- 130 CONTINUE
- *
- * end of main loop.
- * compute square root and adjust for scaling.
- *
- DZNRM2 = DSQRT( SUM )
- IF( SCALE )
- $ DZNRM2 = DZNRM2*XMAX
- 140 CONTINUE
- RETURN
- END
-